import { EventTouch, instantiate, Prefab } from 'cc';
import { Dictionary } from '../../../../../wing/assets/src';
import { app } from '../../application';
import { HintRollingTipInfo } from '../../declarations';
import { ccclass, ccmodifier } from '../../decorators';
import { HintRollingTip } from './HintRollingTip';
import { HintStack } from './HintStack';

/**
 * - 作者: DoooReyn
 * - 日期: 2023.11.02
 * - 名称: HintRollingTipStack
 * - 描述: 滚动提示堆栈
 */
@ccclass()
@ccmodifier('HintRollingTipStack')
export class HintRollingTipStack extends HintStack {
    /** 滚动提示队列 */
    protected _queue: Dictionary<HintRollingTipInfo[]>;

    protected onEnable(): void {
        this.node.on('rolling-began', this.onRollingStart, this);
        this.node.on('rolling-ended', this.onRollingEnded, this);
    }

    protected onDisable(): void {
        this.node.off('rolling-began', this.onRollingStart, this);
        this.node.off('rolling-ended', this.onRollingEnded, this);
    }

    /** 屏幕被点击时调用 */
    protected onTouchScreen(e: EventTouch) {
        e.preventSwallow = true;
    }

    /**
     * 添加滚动提示
     * @param cfg 滚动提示配置
     */
    async addTip(cfg: HintRollingTipInfo) {
        cfg.bundle ??= 'resources';
        const key = `${cfg.bundle}/${cfg.path}`;
        if (this._queue.has(key)) {
            this._queue.fetch(key)!.push(cfg);
            this.onNewComing(key);
        } else {
            this._queue.add(key, [cfg]);
            this.onNext(key);
        }
    }

    /**
     * 开始滚动时调用
     * @param comp 滚动提示组件
     */
    protected onRollingStart(comp: HintRollingTip) {}

    /**
     * 完成滚动时调用
     * @param comp 滚动提示组件
     */
    protected async onRollingEnded(comp: HintRollingTip) {
        const queue = this._queue.fetch(comp.key);
        if (queue && queue.length > 0) {
            const cfg = queue.shift()!;
            await comp.show(cfg, true);
        } else {
            await comp.hide();
        }
    }

    /**
     * 新的滚动提示出现时调用
     * @param key 滚动提示的 key
     */
    protected async onNewComing(key: string) {
        // 查找是否有对应 key 的前台滚动提示
        let found = false;
        const children = this.node.children;
        for (let i = 0; i < children.length; i++) {
            let child = children[i];
            if ((child as any).key === key) {
                found = true;
                break;
            }
        }
        if (!found) {
            // 没有发现前台滚动提示时，创建滚动提示
            this.onNext(key);
        }
    }

    /**
     * 显示下一个滚动提示
     * @param key 滚动提示的 key
     */
    protected async onNext(key: string) {
        const queue = this._queue.fetch(key);
        if (queue && queue.length > 0) {
            const cfg = queue.shift()!;
            const prefab = await app.resLoader.loadOne({ bundle: cfg.bundle, path: cfg.path, type: Prefab });
            if (prefab && prefab.data.getComponent(HintRollingTip)) {
                const node = instantiate(prefab);
                (node as any).__key = key;
                const comp = node.getComponent(HintRollingTip)!;
                this.node.addChild(node);
                await comp.show(cfg);
            }
        }
    }

    async enter(): Promise<void> {
        await this.hide();
        this.logger.debug('进入舞台');
    }

    async exit() {
        this._queue?.clear();
        this.node.destroyAllChildren();
        await super.exit();
    }
}
